package com.ncepu.thumb.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.BasicPolymorphicTypeValidator;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.ncepu.thumb.mq.rabbit.constant.RabbitMQConstant;

import com.ncepu.thumb.mq.msg.ThumbEvent;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;


/**
 * @author simon_jiang
 * @version 1.0
 */
@Configuration
public class RabbitMQConfig {

    // 死信交换机
    @Bean
    public DirectExchange deadLetterExchange() {
        return new DirectExchange(RabbitMQConstant.DEAD_DIRECT_EXCHANGE, true, false);
    }

    // 死信队列
    @Bean
    public Queue deadLetterQueue() {
        return new Queue(RabbitMQConstant.DEAD_QUEUE,true,  false, false);
    }

    // 绑定死信队列到死信交换机
    @Bean
    public Binding deadLetterBinding() {
        return BindingBuilder.bind(deadLetterQueue()).to(deadLetterExchange()).with(RabbitMQConstant.DEAD_ROUTING_KEY);
    }

    @Bean
    public DirectExchange directExchange() {
        return new DirectExchange(RabbitMQConstant.DIRECT_EXCHANGE, true, false);
    }

    @Bean
    public Queue myQueue() {
        return new Queue(RabbitMQConstant.QUEUE, true, false, false);
    }

    @Bean
    public Binding binding() {
        return BindingBuilder.bind(myQueue()).to(directExchange()).with(RabbitMQConstant.ROUTING_KEY);
    }

    @Bean
    public Jackson2JsonMessageConverter jackson2JsonMessageConverter() {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.registerModule(new JavaTimeModule()); // 注册 JavaTimeModule
        objectMapper.activateDefaultTyping(
                BasicPolymorphicTypeValidator.builder()
                        .allowIfSubType(ThumbEvent.class) // 显式允许 ThumbEvent 类
                        .build(),
                ObjectMapper.DefaultTyping.NON_FINAL
        );
        return new Jackson2JsonMessageConverter(objectMapper);
    }

    @Bean(name = "customRabbitTemplate")
    public RabbitTemplate customRabbitTemplate(ConnectionFactory connectionFactory, RedisTemplate<String, Object> redisTemplate) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        rabbitTemplate.setMessageConverter(jackson2JsonMessageConverter());

        // 设置 ConfirmCallback
        rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
            if (!ack && correlationData != null && correlationData.getId() != null) {
                String[] data = correlationData.getId().split(":");
                String operation = data[0];
                String userThumbKey = data[1];
                String blogId = data[2];

                if ("INCR".equals(operation)) {
                    redisTemplate.opsForZSet().remove(userThumbKey, blogId);
                } else if ("DECR".equals(operation)) {
                    redisTemplate.opsForZSet().add(userThumbKey, blogId, System.currentTimeMillis());
                }
                System.err.println("消息发送失败，原因：" + cause);
            }
        });
        return rabbitTemplate;
    }
//    @Primary
//    @Bean
//    public RabbitTemplate rabbitTemplate(RabbitTemplate rabbitTemplate, RedisTemplate<String, Object> redisTemplate) {
//        rabbitTemplate.setConfirmCallback((CorrelationData correlationData, boolean ack, String cause) -> {
//            if (!ack && correlationData != null && correlationData.getId() != null) {
//                String[] data = correlationData.getId().split(":");
//                String operation = data[0]; // 操作类型（INCR 或 DECR）
//                String userThumbKey = data[1];
//                String blogId = data[2];
//
//                if ("INCR".equals(operation)) {
//                    // 点赞回滚
//                    redisTemplate.opsForZSet().remove(userThumbKey, blogId);
//                } else if ("DECR".equals(operation)) {
//                    // 取消点赞回滚
//                    redisTemplate.opsForZSet().add(userThumbKey, blogId, System.currentTimeMillis());
//                }
//                System.err.println("消息发送失败，原因：" + cause);
//            }
//        });
//        return rabbitTemplate;
//    }

}
